package com.iuie.ns.datum.service.impl;

import java.util.List;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.iuie.ns.datum.mapper.TableFieldMapper;
import com.iuie.ns.datum.service.ITableFieldService;
import com.iuie.ns.datum.service.ITableStructureService;
import com.iuie.ns.datum.vo.TableFieldVO;
import com.iuie.ns.datum.vo.TableStructureVO;
import com.iuie.ns.frame.exception.ServiceException;
import com.iuie.ns.frame.utils.ListUtils;
import com.iuie.ns.frame.utils.StringUtils;
import com.iuie.ns.system.factory.BatchBuildeObjectFactory;
import com.iuie.ns.system.maker.BatchMaker;
import com.iuie.ns.system.service.code.ISysCodeInfoService;
import com.iuie.ns.system.vo.code.SysCodeInfoVO;

@Service("tableFieldService")
public class TableFieldServiceImpl implements ITableFieldService {
	
	private static final Logger logger = LoggerFactory.getLogger(TableFieldServiceImpl.class);
	
	@Resource
	private TableFieldMapper tableFieldMapper;
	
	@Resource
	private ITableStructureService tableStructureService;
	
	@Resource
	private ISysCodeInfoService codeInfoService;
	
	@Resource
	private BatchBuildeObjectFactory batchObjectFactory;
	
	@Override
	public List<TableFieldVO> findFieldsByTableId(Long tableId) {
		return tableFieldMapper.findFieldsByTableId(tableId);
	}

	@Override
	public void batchAdd(List<TableFieldVO> records) {
		if (ListUtils.isNotEmpty(records)) {
			tableFieldMapper.batchAdd(records);
		}
	}
	
	@Override
	public void deleteFieldsByTableId(Long tableId) {
		Integer count = tableFieldMapper.deleteFieldsByTableId(tableId);
		logger.info("已删除表的字段，其数量 = {}，表ID = {}", count, tableId);
	}

	@Override
	public void saveTableField(TableFieldVO field, String updateRemark) {
		// 1.校验
		if (field == null) {
			throw new ServiceException("保存字段失败，没有数据可保存！");
		}
		if (field.getTableId() == null) {
			throw new ServiceException("保存字段失败，字段对应的表ID不能为空！");
		}
		TableStructureVO table = tableStructureService.findById(field.getTableId());
		if (table == null) {
			throw new ServiceException("保存字段失败，非法的表ID！");
		}
		if (StringUtils.isBlank(field.getFieldType())) {
			throw new ServiceException("保存字段失败，字段类型不能为空！");
		}
		SysCodeInfoVO codeInfo = codeInfoService.findCodeInfoByCodeValueAndCodeType(field.getFieldType(), "fieldType");
		if (codeInfo == null) {
			throw new ServiceException("保存字段失败，非法数据[fieldType]！");
		}
		if (StringUtils.isBlank(field.getFieldName())) {
			throw new ServiceException("保存字段失败，字段名称不能为空！");
		}
		field.setFieldName(StringUtils.upperCase(field.getFieldName())); // 转大写
		TableFieldVO mItem = this.findFieldByFieldName(field.getTableId(), field.getFieldName());
		if (mItem != null) {
			if (field.getId() == null || (field.getId() != null && field.getId().compareTo(mItem.getId()) != 0)) {
				throw new ServiceException("保存失败，项目英文名称与项目【" + mItem.getFieldName() + "】重复！");
			}
		}
		
		if (field.getFieldLength() !=null && field.getFieldLength() > 4000) {
			throw new ServiceException("保存字段失败，字段长度不能超过4000！");
		}
		if (field.getAllowNull() == null) {
			field.setAllowNull("1");
		}
		if (field.getIsPrimaryKey() == null) {
			field.setIsPrimaryKey("0");
		}
		// 如果是主键的话，那么allowNull一定是0
		if (StringUtils.equals(field.getIsPrimaryKey(), "1")) {
			field.setAllowNull("0");
		}
		if (field.getAllowNull().length() > 1 || !(StringUtils.equals(field.getAllowNull(), "0") || StringUtils.equals(field.getAllowNull(), "1"))) {
			throw new ServiceException("保存字段失败，非法数据[allowNull]！");
		}
		if (field.getIsPrimaryKey().length() > 1 || !(StringUtils.equals(field.getIsPrimaryKey(), "0") || StringUtils.equals(field.getIsPrimaryKey(), "1"))) {
			throw new ServiceException("保存字段失败，非法数据[isPrimaryKey]！");
		}
		// 当fieldType为varchar或char，但没设置字段长度时，默认设置字段长度为255
		if (StringUtils.equals(field.getFieldType(), "VARCHAR") || StringUtils.equals(field.getFieldType(), "CHAR")) {
			if (field.getFieldLength() == null) {
				field.setFieldLength(255);
			}
		}
		
		if (field.getId() == null) {
			// 新增
			field.setId(System.currentTimeMillis());
			tableFieldMapper.addOne(field);
		} else {
			// 修改
			tableStructureService.addUpdateHistory(updateRemark, field.getTableId());
			tableFieldMapper.updateOne(field);
		}
	}

	@Override
	public void deleteById(Long id) {
		tableFieldMapper.deleteById(id);
	}

	@Override
	public TableFieldVO findFieldByFieldName(Long tableId, String fieldName) {
		if (tableId == null || fieldName == null) {
			return null;
		}
		return tableFieldMapper.findFieldByFieldName(tableId, fieldName.toUpperCase());
	}

	@Override
	public TableFieldVO findById(Long fieldId) {
		if (fieldId == null) {
			return null;
		}
		return tableFieldMapper.findById(fieldId);
	}

	@Override
	public void updateDoQuery(Long fieldId, String doQuery) {
		if (fieldId == null || StringUtils.isBlank(doQuery)) {
			throw new ServiceException("更新[用于查询的状态]失败，[ID]或属性值为空！");
		}
		tableFieldMapper.updateDoQuery(fieldId, doQuery);
	}

	@Override
	public void updateQueryMode(Long fieldId, String queryMode) {
		if (fieldId == null || StringUtils.isBlank(queryMode)) {
			throw new ServiceException("更新[查询模式]失败，[ID]或属性值为空！");
		}
		tableFieldMapper.updateQueryMode(fieldId, queryMode);
	}

	@Override
	public void updateDoUpdate(Long fieldId, String doUpdate) {
		if (fieldId == null || StringUtils.isBlank(doUpdate)) {
			throw new ServiceException("更新[用于更新的状态]失败，[ID]或属性值为空！");
		}
		tableFieldMapper.updateDoUpdate(fieldId, doUpdate);
	}

	@Override
	public void updateAllowNull(Long fieldId, String allowNull) {
		if (fieldId == null || StringUtils.isBlank(allowNull)) {
			throw new ServiceException("更新[非空]属性失败，[ID]或属性值为空！");
		}
		tableFieldMapper.updateAllowNull(fieldId, allowNull);
	}
	
	@Override
	public void updateIsPrimaryKey(Long fieldId, String isPrimaryKey) {
		if (fieldId == null || StringUtils.isBlank(isPrimaryKey)) {
			throw new ServiceException("更新[主键]属性失败，[ID]或属性值为空！");
		}
		tableFieldMapper.updateIsPrimaryKey(fieldId, isPrimaryKey);
	}
	
	@Override
	public void updateDisplay(Long fieldId, String display) {
		if (fieldId == null) {
			throw new ServiceException("更新[display]属性失败，[ID]为空！");
		}
		tableFieldMapper.updateDisplay(fieldId, display);
	}
	
	@Override
	public void updateComment(Long fieldId, String comment) {
		if (fieldId == null) {
			throw new ServiceException("更新[comment]属性失败，[ID]为空！");
		}
		tableFieldMapper.updateComment(fieldId, comment);
	}
	
	@Override
	public void batchAddField(String text, String rule, Long tableId) {
		if (StringUtils.isBlank(text)) {
			throw new ServiceException("保存失败，text内容为空！");
		}
		if (tableId == null) {
			throw new ServiceException("保存字段失败，字段对应的表ID不能为空！");
		}
		TableStructureVO table = tableStructureService.findById(tableId);
		if (table == null) {
			throw new ServiceException("保存字段失败，非法的表ID！");
		}
		SysCodeInfoVO codeInfo = codeInfoService.findCodeInfoByCodeValueAndCodeType(rule, "mdFieldAddRules");
		if (codeInfo == null) {
			throw new ServiceException("系统中不存在字段新增规则【" + rule + "】");
		}
		// 制造出码值
		BatchMaker<TableFieldVO> maker = batchObjectFactory.getMaker(rule, codeInfo.getExt1());
		List<TableFieldVO> fields = maker.text(text).make();
		
		if (ListUtils.isNotEmpty(fields)) {
			for (TableFieldVO field: fields) {
				field.setTableId(tableId);
				
				if (StringUtils.isBlank(field.getFieldType())) {
					throw new ServiceException("保存字段失败，字段类型不能为空！");
				}
				if (StringUtils.isBlank(field.getAllowNull()) || !(StringUtils.equals(field.getAllowNull(), "0") 
						|| StringUtils.equals(field.getAllowNull(), "1"))) {
					throw new ServiceException("保存字段失败，非法数据[allowNull=" + field.getAllowNull() + "]！");
				}
				if (StringUtils.isBlank(field.getIsPrimaryKey()) || !(StringUtils.equals(field.getIsPrimaryKey(), "0") 
						|| StringUtils.equals(field.getIsPrimaryKey(), "1"))) {
					throw new ServiceException("保存字段失败，非法数据[isPrimaryKey=" + field.getIsPrimaryKey() + "]！");
				}
				if (field.getFieldLength() !=null && field.getFieldLength() > 4000) {
					throw new ServiceException("保存字段失败，字段长度不能超过4000！");
				}
				SysCodeInfoVO fieldTypeCode = codeInfoService.findCodeInfoByCodeValueAndCodeType(field.getFieldType(), "fieldType");
				if (fieldTypeCode == null) {
					throw new ServiceException("保存字段失败，非法数据[fieldType=" + field.getFieldType() + "]！");
				}
				// 新增
				field.setId(System.currentTimeMillis());
				tableFieldMapper.addOne(field);
			}
		}
	}

}
